#include "stm32regs.h"
#include "stm32regbit.h"
#include "stm32_gpio.h"
#include "stm32_usart.h"

#if 1
//#pragma import(__use_no_semihosting)
//标准库需要的支持函数
struct __FILE
{
  int handle;
  /* Whatever you require here. If the only file you are using is */
  /* standard output using printf() for debugging, no file handling */
  /* is required. */
};
/* FILE is typedef’ d in stdio.h. */
FILE __stdout;
//定义_sys_exit()以避免使用半主机模式
void _sys_exit(int x)
{
  x = x;
}
//重定义fputc函数
int fputc(int ch, FILE *f)
{
  while ((USART1->ISR & 0X40) == 0)
    ; //循环发送,直到发送完毕
  USART1->TDR = (u8)ch;
  return ch;
}
#endif

int mywrite(int ch)
{
  while ((USART1->ISR & 0X40) == 0)
    ; //循环发送,直到发送完毕
  USART1->TDR = (u8)ch;
  return ch;
}

void USART1_Config(u32 pclk2, u32 bound)
{
  float temp;
  uint32_t mantissa;
  uint32_t fraction;
  temp = (float)(pclk2 * 1000000) / (bound * 16); //得到USARTDIV@OVER8=0
  mantissa = temp;                                //得到整数部分
  fraction = (temp - mantissa) * 16;              //得到小数部分@OVER8=0
  mantissa <<= 4;
  mantissa += fraction;
  //使能外设时钟
  __IO uint32_t tmpreg;
  SET_BIT(RCC->APB2ENR, RCC_APB2ENR_USART1EN);
  /* Delay after an RCC peripheral clock enabling */
  tmpreg = READ_BIT(RCC->APB2ENR, RCC_APB2ENR_USART1EN);
  (void)tmpreg;
  //使能引脚时钟
  SET_BIT(RCC->AHB2ENR, RCC_AHB2ENR_GPIOCEN);
  /* Delay after an RCC peripheral clock enabling */
  tmpreg = READ_BIT(RCC->AHB2ENR, RCC_AHB2ENR_GPIOAEN);
  (void)tmpreg;
  //GPIO_Alset(GPIOA, 9);
  //GPIO_Alset(GPIOA, 10);
  GPIO_Set(GPIOC, PIN4 | PIN5, GPIO_MODE_AF, GPIO_OTYPE_PP, GPIO_SPEED_50M, GPIO_PUPD_PU); //PC4,PC5,复用功能,上拉输出
  GPIO_AF_Set(GPIOC, 4, 7);                                                                //PC4,AF7
  GPIO_AF_Set(GPIOC, 5, 7);                                                                //PC5,AF7
//使能外设
#if 0
  MODIFY_REG(USART1->CR1,
             (USART_CR1_M | USART_CR1_PCE | USART_CR1_PS |
              USART_CR1_TE | USART_CR1_RE | USART_CR1_OVER8),
             (0x0 | 0x0 | (USART_CR1_TE | USART_CR1_RE) | 0));
  MODIFY_REG(USART1->CR2, USART_CR2_STOP, 0);                  //设置停止位  1
  MODIFY_REG(USART1->CR3, USART_CR3_RTSE | USART_CR3_CTSE, 0); //HardwareFlowControl
#endif
  //设置波特率
  USART1->BRR = 737;         //波特率设置
  USART1->CR1 &= ~(1 << 15); //设置OVER8=0
  USART1->CR1 |= 1 << 3;     //串口发送使能
#if EN_USART1_RX             //如果使能了接收
  //使能接收中断
  USART1->CR1 |= 1 << 2;              //串口接收使能
  USART1->CR1 |= 1 << 5;              //接收缓冲区非空中断使能
  MY_NVIC_Init(3, 3, USART1_IRQn, 2); //组2，最低优先级
#endif
  USART1->CR1 |= 1 << 13; //串口使能
  //return mantissa;
  //printf("hello world\r\n");
}
